﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Compilex.Automata;
using Infraestruturex.Automata.SPA;

namespace Metex
{
    public class SPAfromDFABuilder
    {
        public DFA DFA { get; set; }
        public SPA SPA { get; set; }
        private DFAState[] dfaStates = null;
        private  HashSet<SPAState> spaStates = new HashSet<SPAState>();

        public SPAfromDFABuilder(DFA dfa)
        {
            this.DFA = dfa;
        }

        public SPA BuildSPA(string name)
        {
            SPA = new SPA(name);
            this.dfaStates = DFA.GetStates();
            foreach (DFAState dfaState in dfaStates)
            {
                SPAState spaState = new SPAState(dfaState.Name, dfaState.IsAcceptState);
                spaStates.Add(spaState);
                if(DFA.StartState == dfaState)
                    SPA.StartState = spaState;
            }

            foreach (DFAState dfaState in dfaStates)
            {
                SPAState spaState = spaStates.Where(s => s.Name == dfaState.Name).First();
                foreach (ITransitionRule<DFAState> transition in dfaState.Transitions.ToArray())
                {
                    if(!(transition is SimpleTransitionRule<DFAState>))
                    {
                        throw new ArgumentException("Para ser transformado em SPA, o DFA deve ter todas as suas transições como SimpleTransitionRule<DFAState>");
                    }
                    SimpleTransitionRule<DFAState> dfaTransition =
                        (SimpleTransitionRule<DFAState>) transition;
                    SPAState spaDestination = spaStates.Where(s => s.Name == dfaTransition.Destination.Name).First();
                    spaState.AddTransition(dfaTransition.Input, spaDestination);
                }
            }

            return SPA;
        }
    }
}
